package utils

import (
	"bytes"
	"strconv"
	"strings"
)

var CRON_TIME_CN = []string{"秒", "分", "点", "天", "月", "周", "年"}
var HOURS = 24
var TIMESCALE = 60

// TranslateCronToChinese 识别cron表达式转成中文
func TranslateCronToChinese(cronExp string) string {
	return translateCronToChinese(cronExp, CRON_TIME_CN)
}

func translateCronToChinese(cronExp string, cronTimeArr []string) string {
	// 入参判断
	if cronExp == "" || len(cronTimeArr) < 1 {
		return ""
	}
	tmpCorns := strings.Split(cronExp, " ")
	var sBuffer bytes.Buffer // 声明字节缓冲
	// stringBuilder.WriteString("哈喽")   //把字符串写入缓冲区
	// stringBuilder.WriteString("沃德")
	if len(tmpCorns) == 6 || len(tmpCorns) == 7 {
		if len(tmpCorns) == 7 {
			// 解析年 Year
			year := tmpCorns[6]
			// 0 15 10 L * ? 切割后 len==7 且最后一个是空串。go和java不一样，java length==6
			if year != "*" && year != "?" && year != "" {
				sBuffer.WriteString(year)
				sBuffer.WriteString(cronTimeArr[6])
			}
		}
		// 解析月 Month 主要解析 /
		months := tmpCorns[4]
		if months != "*" && months != "?" {
			if strings.Contains(months, "/") {
				sBuffer.WriteString("从")
				sBuffer.WriteString(strings.Split(months, "/")[0])
				sBuffer.WriteString("号开始")
				sBuffer.WriteString(",每")
				sBuffer.WriteString(strings.Split(months, "/")[1])
				sBuffer.WriteString(cronTimeArr[4])
			} else {
				if strings.Contains(sBuffer.String(), "-") {
					sBuffer.WriteString("每年")
				}
				sBuffer.WriteString(months)
				sBuffer.WriteString(cronTimeArr[4])
			}
		}
		// 解析周 DayofWeek 主要解析 , - 1~7/L 1L~7L
		dayofWeek := tmpCorns[5]
		if dayofWeek != "*" && dayofWeek != "?" {
			if strings.Contains(dayofWeek, ",") {
				sBuffer.WriteString("每周的第")
				sBuffer.WriteString(dayofWeek)
				sBuffer.WriteString(cronTimeArr[3])
			} else if strings.Contains(dayofWeek, "L") && len(dayofWeek) > 1 { // 1L-7L
				weekNum := strings.Split(dayofWeek, "L")[0]
				weekName := judgeWeek(weekNum)
				sBuffer.WriteString("每月的最后一周的")
				sBuffer.WriteString(weekName)
			} else if strings.Contains(dayofWeek, "-") {
				splitWeek := strings.Split(dayofWeek, "-")
				weekOne := judgeWeek(splitWeek[0])
				weekTwo := judgeWeek(splitWeek[1])
				sBuffer.WriteString("每周的")
				sBuffer.WriteString(weekOne)
				sBuffer.WriteString("到")
				sBuffer.WriteString(weekTwo)
			} else { // 1-7/L
				if "L" == (dayofWeek) { // L 转换为7，便于识别
					dayofWeek = "7"
				}
				sBuffer.WriteString("每周的")
				weekName := judgeWeek(dayofWeek)
				sBuffer.WriteString(weekName)
			}
		}
		// 解析日 days -- DayofMonth 需要解析的 / # L W
		// * “6#3”表示本月第三周的星期五（6表示星期五，3表示第三周）;
		// * “2#1”表示本月第一周的星期一;
		// * “4#5”表示第五周的星期三。
		days := tmpCorns[3]
		if days != "?" && days != "*" {
			if strings.Contains(days, "/") {
				sBuffer.WriteString("每周从第")
				sBuffer.WriteString(strings.Split(days, "/")[0])
				sBuffer.WriteString("天开始")
				sBuffer.WriteString(",每")
				sBuffer.WriteString(strings.Split(days, "/")[0])
				sBuffer.WriteString(cronTimeArr[3])
			} else if "L" == days { // 处理L 每月的最后一天
				sBuffer.WriteString("每月最后一天")
			} else if "W" == days { // 处理W 暂时不懂怎么处理
				sBuffer.WriteString(days)
			} else if strings.Contains(days, "#") {
				splitDays := strings.Split(days, "#")
				weekNum := splitDays[0]     // 前面数字表示周几
				weekOfMonth := splitDays[1] // 后面的数字表示第几周 范围1-4 一个月最多4周
				weekName := judgeWeek(weekNum)
				sBuffer.WriteString("每月第")
				sBuffer.WriteString(weekOfMonth)
				sBuffer.WriteString(cronTimeArr[5])
				sBuffer.WriteString(weekName)
			} else {
				sBuffer.WriteString("每月")
				sBuffer.WriteString(days)
				sBuffer.WriteString("号")
			}
		} else {
			sBufferStr := sBuffer.String()
			if (len(sBufferStr) == 0 || len(tmpCorns) == 7) && !strings.Contains(sBufferStr, "星期") {
				// 前面没有内容的话，拼接下
				sBuffer.WriteString("每")
				sBuffer.WriteString(cronTimeArr[3])
			}
		}

		// 解析时 Hours 主要解析 /
		hours := tmpCorns[2]
		if hours != "*" {
			if strings.Contains(hours, "/") {
				sBuffer.WriteString(appendGapInfo(hours, HOURS, 2))
			} else {
				if !(len(sBuffer.String()) > 0) { // 对于 , 的情况，直接拼接
					sBuffer.WriteString("每天")
					sBuffer.WriteString(hours)
					sBuffer.WriteString(cronTimeArr[2])
				} else {
					sBuffer.WriteString(hours)
					sBuffer.WriteString(cronTimeArr[2])
				}
			}
		}

		// 解析分 Minutes 主要解析 /
		minutes := tmpCorns[1]
		if minutes != "*" {
			if strings.Contains(minutes, "/") {
				sBuffer.WriteString(appendGapInfo(minutes, TIMESCALE, 1))
			} else if minutes == "0" {
			} else if strings.Contains(minutes, "-") {
				splitMinute := strings.Split(months, "-")
				sBuffer.WriteString(splitMinute[0])
				sBuffer.WriteString(cronTimeArr[1])
				sBuffer.WriteString("到")
				sBuffer.WriteString(splitMinute[1])
				sBuffer.WriteString(cronTimeArr[1])
				sBuffer.WriteString("每分钟")
			} else {
				sBuffer.WriteString(minutes)
				sBuffer.WriteString(cronTimeArr[1])
			}
		}

		// 解析秒 Seconds 主要解析 /
		seconds := tmpCorns[0]
		if seconds != "*" {
			if strings.Contains(seconds, "/") {
				sBuffer.WriteString(appendGapInfo(seconds, TIMESCALE, 0))
			} else if seconds != "0" {
				sBuffer.WriteString(seconds)
				sBuffer.WriteString(cronTimeArr[0])
			}
		}

		if len(sBuffer.String()) > 0 {
			sBuffer.WriteString("执行")
		} else {
			sBuffer.WriteString("表达式中文转换异常")
		}

	}
	return sBuffer.String()
}

var WeekEnumMap = map[string]string{
	"1": "星期天", "2": "星期一",
	"3": "星期二", "4": "星期三",
	"5": "星期四", "6": "星期五",
	"7": "星期六", "SUN": "星期天",
	"MON": "星期一", "TUE": "星期二",
	"WED": "星期三", "THU": "星期四",
	"FRI": "星期五", "SAT": "星期六",
}

func judgeWeek(weekNum string) string {
	weekName := WeekEnumMap[weekNum]
	if weekName != "" {
		return weekName
	}
	return weekNum
}

func appendGapInfo(time string, rangeNum int, index int) string {
	var sBufferTemp bytes.Buffer
	splitTime := strings.Split(time, "/")
	startNum := splitTime[0]
	gapNum := splitTime[1]
	atoi, err := strconv.Atoi(startNum)
	if err != nil {
		atoi = 0
	}
	atoi2, err := strconv.Atoi(gapNum)
	if err != nil {
		atoi2 = 0
	}
	endNum := rangeNum + atoi - atoi2
	endStr := strconv.Itoa(endNum)
	timeUnit := CRON_TIME_CN[index]
	splitTimeUnit := CRON_TIME_CN[index]
	if index == 1 {
		splitTimeUnit = "分钟"
	} else if index == 2 {
		splitTimeUnit = "小时"
	}
	sBufferTemp.WriteString("从")
	sBufferTemp.WriteString(startNum)
	sBufferTemp.WriteString(timeUnit)
	sBufferTemp.WriteString("开始")
	sBufferTemp.WriteString("到")
	sBufferTemp.WriteString(endStr)
	sBufferTemp.WriteString(timeUnit)
	sBufferTemp.WriteString("范围内")
	sBufferTemp.WriteString(",每隔")
	sBufferTemp.WriteString(gapNum)
	sBufferTemp.WriteString(splitTimeUnit)
	return sBufferTemp.String()
}
